2023/12/234101字符
事件冒泡 & 事件捕获
<div style="width:300px;height:300px;background-color:#f00;margin:0 auto;" class="wrapper">wrapper
<div style="width:200px;height:200px;background-color:#0f0" class="content">content
<div style="width:100px;height:100px;background-color:#00f" class="box">box</div>
</div>
</div>
- 事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
var wrapper = document.getElementsByTagName('div')[0];
var content = document.getElementsByTagName('div')[1];
var box = document.getElementsByTagName('div')[2];
wrapper.addEventListener('click', function(){
console.log('wrapper'); //--> wrapper 事件冒泡
}, false);
content.addEventListener('click', function(){
console.log('content'); //--> content wrapper 事件冒泡
}, false);
box.addEventListener('click', function(){
console.log('box'); //--> box content wrapper 事件执行
}, false);
- 事件捕获(兼容新版浏览器(IE 没有),与事件冒泡相反) 结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
wrapper.addEventListener('click', function(){
console.log('wrapper'); //--> wrapper 事件捕获
}, true);
content.addEventListener('click', function(){
console.log('content'); //--> wrapper content 事件捕获
}, true);
box.addEventListener('click', function(){
console.log('box'); //--> wrapper content box 事件执行
}, true);
// 事件捕获 --> 事件执行 --> 事件冒泡
focus,blur,change,submit,reset,select 等事件不冒泡
取消事件冒泡和默认事件
document.onclick = function () {
console.log('你闲的呀');
}
wrapper.onclick = function (e) {
e = e || window.event; // IE e 事件在 window 下的 event
console.log(e); // 能够返回所有事件信息
e.stopPropagation(); // 取消事件冒泡(IE9 及以下不兼容)
e.cancelBubble = true; // IE 取消事件冒泡
}
封装取消冒泡的函数 stopBubble(event)
function stopBubble (event) {
event = e || window.enent;
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
wrapper.onclick = function () {
stopBubble(e); // 函数调用
}
右键出菜单事件
// 1.
document.oncontextmenu = function(){ // 右键出菜单事件
console.log('a');
return false; // 取消右键菜单事件
}
// 2.
document.addEventListener('contextmenu', function(e){
console.log('a');
e.preventDefault(); // 取消右键菜单事件
e.returnValue = false; // IE 取消右键菜单事件
}, false);
封装阻止默认事件的函数 cancelHandler(event);
function cancelHandler(event){
event = e || window.event;
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
}
事件源对象
wrapper.onclick = function(e){
var e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
<a herf="javascript:void(false)">demo</a> <!-- 协议限定符 a 标签失去点击事件 == return false -->
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>
// 1. 浪费效率
var li = document.getElementsByTagName('li');
var len = li.length;
for(var i = 0; i < len; i ++){
li[i].onclick = function(){
console.log(this.innerText);
}
}
// 2. 利用事件源对象
var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(){
var e = e || window.event;
var target = e.target || event.srcElement;
console.log(target.innerText);
}